/**
 * API 辅助工具
 * 提供重试机制、错误处理、缓存优化等功能
 */

import { http } from '@/http/http'
import { cache } from './cache'

export interface ApiOptions {
  retry?: number // 重试次数
  retryDelay?: number // 重试延迟（毫秒）
  useCache?: boolean // 是否使用缓存
  cacheKey?: string // 缓存键名
  cacheExpire?: number // 缓存过期时间（毫秒）
  hideErrorToast?: boolean // 是否隐藏错误提示
}

export interface ApiResponse<T = any> {
  data: T
  message?: string
  code: number
  timestamp: string
}

/**
 * 通用 API 请求包装器
 */
export async function apiRequest<T>(
  url: string,
  options: any = {},
  apiOptions: ApiOptions = {},
): Promise<T> {
  const {
    retry = 2,
    retryDelay = 1000,
    useCache = false,
    cacheKey,
    cacheExpire = 5 * 60 * 1000, // 默认5分钟
    hideErrorToast = false,
  } = apiOptions

  // 缓存处理
  if (useCache && cacheKey) {
    const cachedData = cache.get<T>(cacheKey)
    if (cachedData) {
      return cachedData
    }
  }

  let lastError: any

  // 重试机制
  for (let attempt = 0; attempt <= retry; attempt++) {
    try {
      const response = await http<T>({
        url,
        ...options,
        hideErrorToast: hideErrorToast || attempt > 0, // 重试时隐藏提示
      })

      // 缓存成功的结果
      if (useCache && cacheKey && response) {
        cache.set(cacheKey, response, cacheExpire)
      }

      return response
    }
    catch (error: any) {
      lastError = error

      // 如果是最后一次尝试或者不需要重试，直接抛出错误
      if (attempt === retry || !shouldRetry(error)) {
        throw error
      }

      // 等待后重试
      await delay(retryDelay * 2 ** attempt) // 指数退避
      console.warn(`API 请求失败，第 ${attempt + 1} 次重试:`, error.message)
    }
  }

  throw lastError
}

/**
 * 判断是否应该重试
 */
function shouldRetry(error: any): boolean {
  const errorMessage = error.message || error.toString().toLowerCase()

  // 网络相关错误可以重试
  return (
    errorMessage.includes('network')
    || errorMessage.includes('timeout')
    || errorMessage.includes('connection')
    || errorMessage.includes('网络')
    || errorMessage.includes('连接')
    || errorMessage.includes('超时')
    || (error.statusCode >= 500 && error.statusCode < 600) // 服务器错误
  )
}

/**
 * 延迟函数
 */
function delay(ms: number): Promise<void> {
  return new Promise(resolve => setTimeout(resolve, ms))
}

/**
 * GET 请求的便捷方法
 */
export function apiGet<T>(
  url: string,
  params?: any,
  apiOptions: ApiOptions = {},
): Promise<T> {
  return apiRequest<T>(url, {
    method: 'GET',
    data: params,
  }, apiOptions)
}

/**
 * POST 请求的便捷方法
 */
export function apiPost<T>(
  url: string,
  data?: any,
  apiOptions: ApiOptions = {},
): Promise<T> {
  return apiRequest<T>(url, {
    method: 'POST',
    data,
  }, apiOptions)
}

/**
 * PUT 请求的便捷方法
 */
export function apiPut<T>(
  url: string,
  data?: any,
  apiOptions: ApiOptions = {},
): Promise<T> {
  return apiRequest<T>(url, {
    method: 'PUT',
    data,
  }, apiOptions)
}

/**
 * DELETE 请求的便捷方法
 */
export function apiDelete<T>(
  url: string,
  apiOptions: ApiOptions = {},
): Promise<T> {
  return apiRequest<T>(url, {
    method: 'DELETE',
  }, apiOptions)
}

/**
 * 批量请求处理器
 */
export async function batchRequest<T>(
  requests: Array<() => Promise<T>>,
  options: {
    concurrent?: boolean // 是否并发执行
    failFast?: boolean // 是否在第一个失败时停止
  } = {},
): Promise<T[]> {
  const { concurrent = true, failFast = false } = options

  if (concurrent) {
    if (failFast) {
      // 并发执行，遇到第一个失败立即停止
      return Promise.all(requests.map(req => req()))
    }
    else {
      // 并发执行，等待所有请求完成
      return Promise.allSettled(requests.map(req => req())).then((results) => {
        return results.map((result, index) => {
          if (result.status === 'fulfilled') {
            return result.value
          }
          else {
            console.error(`批量请求第 ${index + 1} 个失败:`, result.reason)
            throw result.reason
          }
        })
      })
    }
  }
  else {
    // 顺序执行
    const results: T[] = []
    for (let i = 0; i < requests.length; i++) {
      try {
        const result = await requests[i]()
        results.push(result)
      }
      catch (error) {
        if (failFast) {
          throw error
        }
        console.error(`批量请求第 ${i + 1} 个失败:`, error)
        // 继续执行下一个请求
      }
    }
    return results
  }
}

/**
 * 请求队列管理器
 */
export class RequestQueue {
  private queue: Array<() => Promise<any>> = []
  private running = false
  private maxConcurrent = 3

  constructor(maxConcurrent = 3) {
    this.maxConcurrent = maxConcurrent
  }

  /**
   * 添加请求到队列
   */
  add<T>(request: () => Promise<T>): Promise<T> {
    return new Promise((resolve, reject) => {
      this.queue.push(async () => {
        try {
          const result = await request()
          resolve(result)
        }
        catch (error) {
          reject(error)
        }
      })
      this.processQueue()
    })
  }

  /**
   * 处理队列
   */
  private async processQueue() {
    if (this.running || this.queue.length === 0) {
      return
    }

    this.running = true
    const batch = this.queue.splice(0, this.maxConcurrent)

    try {
      await Promise.all(batch.map(task => task()))
    }
    catch (error) {
      console.error('请求队列处理失败:', error)
    }

    this.running = false

    // 如果还有待处理的请求，继续处理
    if (this.queue.length > 0) {
      setImmediate(() => this.processQueue())
    }
  }

  /**
   * 清空队列
   */
  clear() {
    this.queue = []
    this.running = false
  }
}

// 创建默认的请求队列实例
export const defaultRequestQueue = new RequestQueue()
